package com.mlnx.device.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mlnx.analysis.pojo.dto.EcgChannel;
import com.mlnx.common.form.PageForm;
import com.mlnx.device.dao.mysql.EcgDeviceMapper;
import com.mlnx.device.entity.Device;
import com.mlnx.device.entity.EcgDevice;
import com.mlnx.device.pojo.dto.EcgDeviceDto;
import com.mlnx.device.pojo.form.EcgDeviceFilterForm;
import com.mlnx.device.pojo.form.EcgDeviceForm;
import com.mlnx.device.pojo.form.EcgFilterInfoForm;
import com.mlnx.device.service.DeviceService;
import com.mlnx.device.service.EcgDeviceService;
import com.mlnx.device.session.core.EcgDeviceSession;
import com.mlnx.device.session.manager.MutilDeviceSessionManager;
import com.mlnx.device.util.SortUtil;
import com.mlnx.service.base.service.BaseService;
import com.mlnx.service.common.enums.ResponseEnum;
import com.mlnx.service.common.exception.MutilDeviceServiceException;
import org.shan.mq.session.core.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by amanda.shan on 2019/10/25.
 */
@Service
public class EcgDeviceServiceIml extends BaseService<EcgDeviceMapper, EcgDevice> implements EcgDeviceService {
    @Autowired
    @Override
    public void setBaseMapper(EcgDeviceMapper baseMapper) {
        super.setBaseMapper(baseMapper);
    }

    @Autowired
    private MutilDeviceSessionManager sessionManager;

    @Autowired
    private DeviceService deviceService;

    @Override
    public Collection<String> getOnlineEcgDeviceNums() {

        Collection<String> ecgDeviceIds = sessionManager.getEcgDeviceIds();

        return ecgDeviceIds;
    }

    @Override
    public EcgDeviceDto getEcgDeviceDto(String deviceId) {
        return baseMapper.selectEcgDeviceDto(deviceId);
    }

    @Override
    public List<EcgDeviceDto> getOnlineEcgDevices() {
        Collection<String> onlineEcgDevices = getOnlineEcgDeviceNums();

        List<EcgDeviceDto> ecgDevices = null;
        if (onlineEcgDevices != null && onlineEcgDevices.size() > 0) {
            Map<String, Object> paramMap = new HashMap();
            paramMap.put("list", onlineEcgDevices);
            ecgDevices = baseMapper.selectEcgDevicesByNumList(paramMap);
        }

        return ecgDevices;
    }

    @Override
    public List<EcgDeviceDto> getAllEcgDevices() {

        List<EcgDeviceDto> ecgDevices = baseMapper.selectAllEcgDevices();

        List<String> deviceIds = ecgDevices.stream().map(EcgDeviceDto::getNumeration).collect(Collectors.toList());

        Collection<String> onlineDeviceIds = sessionManager.getOnlineDeviceIds(deviceIds);

        if (ecgDevices != null && ecgDevices.size() > 0 && onlineDeviceIds != null && onlineDeviceIds.size() > 0) {
            for (EcgDeviceDto ecgDevice : ecgDevices) {
                for (String onlineDeviceId : onlineDeviceIds) {
                    if (ecgDevice.getNumeration().equals(onlineDeviceId)) {
                        ecgDevice.setState(1);
                        break;
                    }
                }
            }
        }

        return ecgDevices;
    }

    @Override
    public Page<EcgDeviceDto> list(PageForm pageForm, EcgDeviceFilterForm ecgDeviceFilterForm) {
        Page<EcgDeviceDto> ecgDeviceDtoPage = baseMapper.selectDeviceDtoPage(new Page<EcgDeviceDto>(pageForm.getCurrent(),
                pageForm.getSize()), ecgDeviceFilterForm, SortUtil.parseSorter(ecgDeviceFilterForm.getSorter()));

        List<String> deviceIds = ecgDeviceDtoPage.getRecords().stream().map(EcgDeviceDto::getNumeration).collect(Collectors.toList());

        Collection<String> onlineDeviceIds = sessionManager.getOnlineDeviceIds(deviceIds);

        if (ecgDeviceDtoPage.getRecords() != null && ecgDeviceDtoPage.getRecords().size() > 0 && onlineDeviceIds != null && onlineDeviceIds.size() > 0) {
            for (EcgDeviceDto ecgDeviceDto : ecgDeviceDtoPage.getRecords()) {
                for (String onlineDeviceId : onlineDeviceIds) {
                    if (ecgDeviceDto.getNumeration().equals(onlineDeviceId)) {
                        ecgDeviceDto.setState(1);
                        break;
                    }
                }
            }
        }

        return ecgDeviceDtoPage;
    }

    @Override
    public List<EcgDeviceDto> listOnlines(EcgDeviceFilterForm ecgDeviceFilterForm) {
        Page<EcgDeviceDto> ecgDeviceDtoPage = baseMapper.selectDeviceDtoPage(new Page<EcgDeviceDto>(1l,
                1000l), ecgDeviceFilterForm, SortUtil.parseSorter(ecgDeviceFilterForm.getSorter()));

        List<String> deviceIds = ecgDeviceDtoPage.getRecords().stream().map(EcgDeviceDto::getNumeration).collect(Collectors.toList());

        Collection<String> onlineDeviceIds = sessionManager.getOnlineDeviceIds(deviceIds);

        List<EcgDeviceDto> onlines = new ArrayList<>();

        if (ecgDeviceDtoPage.getRecords() != null && ecgDeviceDtoPage.getRecords().size() > 0 && onlineDeviceIds != null && onlineDeviceIds.size() > 0) {
            for (EcgDeviceDto ecgDeviceDto : ecgDeviceDtoPage.getRecords()) {
                for (String onlineDeviceId : onlineDeviceIds) {
                    if (ecgDeviceDto.getNumeration().equals(onlineDeviceId)) {
                        Session session = sessionManager.getSession(onlineDeviceId);
                        if (session == null) {
                            log.info("设备：" + onlineDeviceId + "已离线");
                            break;
                        }
                        ecgDeviceDto.setState(1);
                        ecgDeviceDto.setLastPacketTime(session.getLastPacketTime());
                        onlines.add(ecgDeviceDto);
                        break;
                    }
                }
            }


        }

        return onlines;
    }

    @Override
    public void modifyEcgFilter(EcgFilterInfoForm ecgFilterInfoForm) {

        getEcgDeviceSession(ecgFilterInfoForm.getDeviceId()).getAnalysis().setEcgFilter(ecgFilterInfoForm.getEcgFilter());
    }

    @Override
    public void modifyEcgChannel(EcgChannel ecgChannel) {

        getEcgDeviceSession(ecgChannel.getDeviceId()).getAnalysis().setBpmCalcLead(ecgChannel.getChannel());
    }

    @Override
    @Transactional
    public void addEcgDevice(EcgDeviceForm ecgDeviceForm,Integer userId) {
        Device device = new Device();
        device.setNumeration(ecgDeviceForm.getNumeration());
        device.setValidTime(ecgDeviceForm.getValidTime());
        device.setDeviceTypeId(ecgDeviceForm.getDeviceType());
        device.setPatientId(ecgDeviceForm.getPatientId() == null ? 0 : ecgDeviceForm.getPatientId());
        device.setUserId(userId);
        deviceService.save(device);

        try {
            EcgDevice ecgDevice = new EcgDevice();
            ecgDevice.setId(device.getId());
            ecgDevice.setEcgDeviceRunMode(ecgDeviceForm.getEcgDeviceRunMode());
            ecgDevice.setEcgChannelType(ecgDeviceForm.getEcgChannelType());
            ecgDevice.setCpuId(ecgDeviceForm.getCpuId());

            save(ecgDevice);
        } catch (Exception e) {
            log.error(e, "保存心电设备异常");
            throw new MutilDeviceServiceException(ResponseEnum.ServerError.getCode(), e.getMessage());
        }
    }

    @Override
    @Transactional
    public void updateEcgDevice(Integer id, EcgDeviceForm ecgDeviceForm) {
        Device device = new Device();
        device.setId(id);
        device.setNumeration(ecgDeviceForm.getNumeration());
        device.setValidTime(ecgDeviceForm.getValidTime());
        if (ecgDeviceForm.getPatientId() != null) {
            device.setPatientId(ecgDeviceForm.getPatientId());
            deviceService.bindDevice(ecgDeviceForm.getPatientId(), ecgDeviceForm.getNumeration());
        }

        deviceService.updateById(device);


        try {
            EcgDevice ecgDevice = new EcgDevice();
            ecgDevice.setId(id);
            ecgDevice.setEcgDeviceRunMode(ecgDeviceForm.getEcgDeviceRunMode());
            ecgDevice.setEcgChannelType(ecgDeviceForm.getEcgChannelType());
            ecgDevice.setCpuId(ecgDeviceForm.getCpuId());

            updateById(ecgDevice);
        } catch (Exception e) {
            e.printStackTrace();
            throw new MutilDeviceServiceException(ResponseEnum.ServerError);
        }

    }

    private EcgDeviceSession getEcgDeviceSession(String deviceId) {
        Session session = sessionManager.getSession(deviceId);

        if (session == null) {
            throw new MutilDeviceServiceException(ResponseEnum.DeviceNotOnline);
        }

        if (session instanceof EcgDeviceSession) {
            EcgDeviceSession ecgDeviceSession = (EcgDeviceSession) session;
            return ecgDeviceSession;
        } else {
            throw new MutilDeviceServiceException(ResponseEnum.NotEcgDevice);
        }
    }
}
